package com.hellobike.haxing.modules.product.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.hellobike.haxing.modules.product.constant.Constants;
import com.hellobike.haxing.modules.product.entity.Category;
import com.hellobike.haxing.modules.product.entity.Product;
import com.hellobike.haxing.modules.product.entity.Sku;
import com.hellobike.haxing.modules.product.entity.Spu;
import com.hellobike.haxing.modules.product.mapper.CategoryMapper;
import com.hellobike.haxing.modules.product.mapper.ProductMapper;
import com.hellobike.haxing.modules.product.mapper.SkuMapper;
import com.hellobike.haxing.modules.product.mapper.SpuMapper;
import com.hellobike.haxing.modules.product.service.IProductService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 售卖商品
 * @Author: haxing-boot
 * @Date:   2020-01-17
 * @Version: V1.0
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private CategoryMapper categoryMapper;


    @Override
    public IPage<Product> page(Page<Product> page, QueryWrapper<Product> queryWrapper) {
        IPage<Product> pageList = productMapper.selectPage(page, queryWrapper);
        //填充分类名称
        fillCategoryNames(pageList.getRecords());
        return pageList;
    }

    @Override
    public List<Product> getByIds(List<Long> idList) {
        List<Product> productList = productMapper.selectBatchIds(idList);
        //填充分类名称
        fillCategoryNames(productList);
        //按照原参数中顺序排序
        Map<Long, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getId, Function.identity()));
        productList = idList.stream().map(id -> productMap.get(id)).filter(o -> o != null).collect(Collectors.toList());
        return productList;
    }

    //填充分类名称
    private void fillCategoryNames(List<Product> productList) {
        if (productList != null && productList.size() > 0) {
            Set<Long> categoryIds = new HashSet<>();
            productList.forEach(product -> {
                categoryIds.add(product.getCategoryId1());
                categoryIds.add(product.getCategoryId2());
                categoryIds.add(product.getCategoryId3());
            });
            List<Category> categoryList = categoryMapper.selectBatchIds(categoryIds);
            Map<Long, String> categoryNameMap = categoryList.stream().collect(Collectors.toMap(Category::getId, Category::getName));
            productList.forEach(product -> {
                product.setCategoryName1(categoryNameMap.get(product.getCategoryId1()));
                product.setCategoryName2(categoryNameMap.get(product.getCategoryId2()));
                product.setCategoryName3(categoryNameMap.get(product.getCategoryId3()));
            });
        }
    }

    @Transactional
    @Override
    public void saveProduct(Product product) {
        Spu spu = spuMapper.selectById(product.getSpuId());
        if (spu == null) {
            throw new RuntimeException("SPU信息不存在");
        }
        if (spu.getStatus() != 3) {
            throw new RuntimeException("非审核通过的SPU不能创建售卖信息");
        }
        setRedundancyInfo(product, spu);
        product.setId(product.getSpuId());
        productMapper.insert(product);
        //保存sku列表
        saveSkus(product);
    }

    //保存sku列表(售卖信息仅更新图片)
    private void saveSkus(Product product) {
        if (product.getSkus() != null) {
            for (Sku sku : product.getSkus()) {
                Sku updateSku = new Sku();
                updateSku.setId(sku.getId());
                updateSku.setImage(sku.getImage());
                skuMapper.updateById(updateSku);
            }
        }
    }

    //设置冗余信息
    private void setRedundancyInfo(Product product, Spu spu) {
        product.setType(spu.getType());
        product.setSpuCode(spu.getSpuCode());
        product.setCategoryId1(spu.getCategoryId1());
        product.setCategoryId2(spu.getCategoryId2());
        product.setCategoryId3(spu.getCategoryId3());
        product.setDimensions(spu.getDimensions());
        //商品说明改成从SPU信息中获取
        JSONArray specifications = new JSONArray();
        if (StringUtils.isNotBlank(spu.getNetContent())) {
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("name", "净含量");
            jsonObject1.put("value", spu.getNetContent());
            specifications.add(jsonObject1);
        }
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("name", "保存条件");
        jsonObject2.put("value", Strings.nullToEmpty(Constants.storeTypeMap.get(spu.getStoreType())));
        specifications.add(jsonObject2);
        JSONObject jsonObject3 = new JSONObject();
        jsonObject3.put("name", "保质期");
        jsonObject3.put("value", (spu.getShelfLife() == null ? "" : spu.getShelfLife()) + Strings.nullToEmpty(Constants.shelfLifeUnitMap.get(spu.getShelfLifeUnit())));
        specifications.add(jsonObject3);
        product.setSpecifications(specifications);
    }

    @Transactional
    @Override
    public void updateProduct(Product product) {
        Spu spu = spuMapper.selectById(product.getId());
        setRedundancyInfo(product, spu);
        productMapper.updateById(product);
        //保存sku列表
        saveSkus(product);
    }

    @Override
    public Product getProductDetail(Long id) {
        Product product = productMapper.selectById(id);
        if (product == null) {
            Spu spu = spuMapper.selectById(id);
            if (spu != null) {
                product = new Product();
                product.setSpuId(id);
            }
        }
        if (product != null) {
            List<Sku> skus = skuMapper.selectList(new QueryWrapper<Sku>().lambda().eq(Sku::getSpuId, id));
            product.setSkus(skus);
        }
        return product;
    }

}
